<template>
  <div>
    <a-row justify="left" style="padding-top: 1rem; padding-bottom: 1rem">
      <a-col span="24">
        <a-form layout="inline">
          <a-form-item label="查询时间" :labelCol="{ style: 'width:60px' }">
            <a-range-picker v-model:value="tmrange" show-time :allowClear="false" />
            <!-- <a-range-picker :defaultValue="tmrange" show-time /> -->
          </a-form-item>
          <a-form-item label="查询对象" :labelCol="{ style: 'width:60px' }">
            <a-cascader
              v-model:value="stcd"
              :options="stcdOptions"
              :show-search="{ searchFilter }"
              :show-checked-strategy="Cascader.SHOW_CHILD"
              style="width: 450px"
              :multiple="false"
              max-tag-count="responsive"
              placeholder="Please select"
            />
          </a-form-item>

          <a-form-item>
            <a-tooltip title="选择数据统计条件">
              <a-button @click="onExchangeDataStatisticButtonClick">
                <PieChartOutlined />
              </a-button>
            </a-tooltip>
          </a-form-item>
          <!-- 由后端返回多个查询方法，在此动态生成查询按钮 -->
          <a-form-item v-for="sql in allSqls">
            <!-- 查询数据按钮 -->
            <a-button
              v-if="sql.optype === 0 || sql.optype === '0'"
              type="primary"
              @click="onExchangeDataQueryButtonClick(sql)"
            >
              <SearchOutlined />{{ sql.name }}
            </a-button>
            <!-- 修改、更新数据按钮 -->
            <!-- <a-button
              v-else-if="sql.optype === 1 || sql.optype === '1'"
              type="success"
              @click="onExchangeDataQueryButtonClick(sql.code)"
              ><EditOutlined />{{ sql.name }}</a-button
            > -->
            <!-- 删除数据按钮 -->
            <!-- <a-button
              v-else-if="sql.optype === 2 || sql.optype === '2'"
              type="error"
              @click="onExchangeDataQueryButtonClick(sql.code)"
              ><DeleteOutlined />{{ sql.name }}</a-button
            > -->
            <!-- 写入等其他按钮 -->
            <!-- <a-button v-else type="primary" @click="onExchangeDataQueryButtonClick(sql.code)">{{
              sql.name
            }}</a-button> -->
          </a-form-item>
          <a-form-item>
            <a-button type="primary" @click="onOpenTimeStsConditionModalClick"> 查询统计 </a-button>
          </a-form-item>
          <!-- <p>{{ stcd }}</p> -->
          <!-- <p>{{ tmrange }}</p> -->
        </a-form>
      </a-col>
    </a-row>
    <a-spin tip="Loading..." :spinning="dataLoading">
      <a-tabs v-model:activeKey="activeTabKey" type="card" size="small">
        <a-tab-pane key="1">
          <template #tab>
            <span>
              <TableOutlined />
              数据表格
            </span>
          </template>
          <BasicTable
            :title="moduleTitle"
            :columns="tableColumns"
            :dataSource="tableData"
            :bordered="true"
            :pagination="false"
            :scroll="{ x: false, y: 'calc(100vh - 320px)' }"
            size="small"
          >
            <template #toolbar>
              <Tooltip title="录入数据">
                <a-button
                  v-if="(currentSqlEditFlag & 0x1) === 0x1"
                  type="success"
                  size="small"
                  @click="onExchangeDataAddButtonClick()"
                >
                  <PlusOutlined />
                </a-button>
              </Tooltip>
              <a-button type="primary" @click="onExchangeDataLogView" style="margin-left: 10px"
                >日志查询</a-button
              >
            </template>
          </BasicTable>
        </a-tab-pane>
        <a-tab-pane key="2">
          <template #tab>
            <span>
              <LineChartOutlined />
              数据图表
            </span>
          </template>
          <TimeSeriesChart
            :title="
              stationname +
              ' ' +
              moment(chartMinTime).format('YYYY-MM-DD') +
              '至' +
              moment(chartMaxTime).format('YYYY-MM-DD')
            "
            :key="chartComponentKey"
            :minTime="chartMinTime"
            :maxTime="chartMaxTime"
            :timetype="chartTimeType"
            :yaxis="chartYAxis"
            :series="chartSeries"
          />
        </a-tab-pane>

        <a-tab-pane key="3">
          <template #tab>
            <span>
              <PieChartOutlined />
              数据统计
            </span>
          </template>
          <DataStatisticsResult :statisticsResult="statisticsResult" />
        </a-tab-pane>
        <a-tab-pane key="4" v-if="tmstsResult">
          <template #tab>
            <span>
              <BarChartOutlined />
              时间规整统计
            </span>
          </template>
          <TimeStsChart
            title=""
            :key="chartComponentKey2"
            :minTime="chartMinTime2"
            :maxTime="chartMaxTime2"
            :timetype="chartTimeType2"
            :yaxis="chartYAxis2"
            :series="chartSeries2"
          />
        </a-tab-pane>
      </a-tabs>
    </a-spin>
    <!-- 新增或修改弹窗组件--使用公用的CRUD功能中的编辑组件 -->
    <CrudEditForm @register="registerSaveModal" @success="opSuccess" />
    <SetStatisticsCondition
      @register="registerDataStsForm"
      @success="onStatisticsConfirmButtonClick"
    />
    <SetTimeStsCondition
      @register="registerTimeStsForm"
      @success="onExchangeTimeStsQueryButtonClick"
    />
    <ExchangeDataLog @register="registerExchangeDataLog" @success="opSuccess" />
  </div>
</template>
<script lang="ts">
  import {
    defineComponent,
    ref,
    onBeforeMount,
    onUnmounted,
    h,
    watch,
    onMounted,
    nextTick,
  } from 'vue';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { useRouter } from 'vue-router';

  import { useMessage } from '/@/hooks/web/useMessage';

  import { CascaderProps, Tooltip, Button, notification } from 'ant-design-vue';
  import { Cascader } from 'ant-design-vue';
  import type { ShowSearchType } from 'ant-design-vue/es/cascader';

  import { ExchangeConfigQueryConditionDto } from '/@/api/qms/model/exchangeConfigModel';
  import {
    ExchangeDataQueryConditionDto,
    DataRecordStatisticsConditionDto,
    ExchangeDataStatisticsResultDto,
    ExchangeStationDto,
  } from '/@/api/qms/model/exchangeDataModel';
  import { DBTableSqlSimpleDto } from '/@/api/platform/model/dbtableSqlModel';
  import { defaultExchangeStatisticsCondition } from './exchangeData.data';
  import {
    getQueryConditionData,
    queryExchangeDataAsRawData,
    regularByTime,
    getSaveExchangeDataApiUrl,
  } from '/@/api/qms/exchangeData';
  import { DBTableColumnDto } from '/@/api/platform/model/dbtableColumnModel';

  import { ChartYAxisProps, TimeSeriesProps } from '/@/components/QuCheng/Charts/ChartProps';

  import { getBasicColumnByColumnDto, getFormSchemaByColumn } from '/@/utils/schemaUtil';

  import { BasicTable, BasicColumn } from '/@/components/Table';
  import TimeSeriesChart from '/@/components/QuCheng/Charts/TimeSeriesChart.vue';
  import TimeStsChart from '/@/components/QuCheng/Charts/TimeStsChart.vue';
  import CrudEditForm from './../../../sys/common-crud/Edit.vue';
  import SetStatisticsCondition from './SetStatisticsCondition.vue';
  import SetTimeStsCondition from './SetTimeStsCondition.vue';
  import DataStatisticsResult from './DataStatisticsResult.vue';
  import { formatToDateTime, formatToDate, dateUtil } from '/@/utils/dateUtil';
  import { numberFormatToString } from '/@/utils/numberUtil';
  import dayjs from 'dayjs';
  import type { Dayjs } from 'dayjs';
  import moment from 'moment';
  import { Tag } from 'ant-design-vue';

  import {
    SearchOutlined,
    PlusOutlined,
    EditOutlined,
    DeleteOutlined,
    TableOutlined,
    LineChartOutlined,
    PieChartOutlined,
    BarChartOutlined,
  } from '@ant-design/icons-vue';
  import { useModal } from '/@/components/Modal';
  import { QcUnifyTransToChildProps } from '/#/QcUnify';
  import { OperationTypeEnum } from '/@/enums/appEnum';
  import { format } from 'path';
  import ExchangeDataLog from './ExchangeDataLog.vue';
  const { createErrorModal } = useMessage();
  const [registerSaveModal, { openModal: openSaveModal }] = useModal();
  const [registerDataStsForm, { openModal: openDataStsFormModal }] = useModal();
  const [registerTimeStsForm, { openModal: openTimeStsFormModal }] = useModal();
  const [registerExchangeDataLog, { openModal: openExchangeDataLogModal }] = useModal();
  export default defineComponent({
    name: 'QmsExchangeDataIndex',
    components: {
      SearchOutlined,
      PlusOutlined,
      EditOutlined,
      DeleteOutlined,
      TableOutlined,
      LineChartOutlined,
      PieChartOutlined,
      BarChartOutlined,
      DataStatisticsResult,
      Tag,
      BasicTable,
      CrudEditForm,
      SetStatisticsCondition,
      SetTimeStsCondition,
      TimeSeriesChart,
      TimeStsChart,
      Tooltip,
      Button,
      ExchangeDataLog,
    },
    //要再setup函数中获取或使用props，需要在setup函数中获取props对象
    setup() {
      const router = useRouter();
      const { t } = useI18n();
      const endIndex = ref(100);
      type RangeTimeType = [Dayjs, Dayjs];

      /**
       * 查询条件中的时间范围值
       */
      const tmrange = ref<RangeTimeType>([
        dayjs(dayjs().startOf('date').format('YYYY-MM-DD HH:mm:ss')),
        dayjs(dayjs().endOf('date').format('YYYY-MM-DD HH:mm:ss')),
      ]);

      const tmstsResult = ref();

      //级联选中的默认选中项，可以指定选中多个，赋值为：[ [ 1, 1, "53010002" ], [ 1, 2, "53010001" ] ]
      //设置为不能多选时，初始选中第1个赋值为：[ [ 1, 1, "53010002" ] ]；人工操作选中1个赋值为：[ 1, 2, "53010002" ]
      const stcd = ref();
      //级联选择的数据源，数组对象，每个节点的属性：value、label、children
      const stcdOptions = ref<CascaderProps['options']>();

      //级联选择支持搜索功能
      const searchFilter: ShowSearchType['filter'] = (inputValue, path) => {
        return path.some(
          (option) => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1,
        );
      };

      /**
       * 后台返回的所有sql集合，用于生成界面中的对应操作按钮
       */
      const allSqls = ref();

      /**
       * 默认查询数据sql对象，用于对数据进行新增、修改等操作后刷新表格使用
       */
      const defaultQuerySql = ref<DBTableSqlSimpleDto | undefined>();

      /**
       * 当前模块的显示数据的表格标题，显示交换数据分类名称信息
       */
      const moduleTitle = ref<string>('数据表格');
      /**
       * 选择站点的名称
       */
      const stationname = ref('');
      /**
       * 当前模块的显示数据的表格列集合
       */
      const tableColumns = ref<BasicColumn[]>([]);
      /**
       * 当前模块的编辑表单列集合，因为新增和修改时表单Schema会略有不同，因此需要根据不同操作再生成Schema
       */
      const editFormColumns = ref<DBTableColumnDto[]>([]);
      /**
       * 当前模块的显示数据的数据源
       */
      const tableData = ref([]);
      const totalData = ref([]);
      /**
       * 交换数据分类集合信息
       */
      const categoriesData = ref([]);
      /**
       * 数据统计结果
       */
      const statisticsResult = ref<ExchangeDataStatisticsResultDto>(null);
      /**
       * 数据统计条件stsCondition
       */
      const statisticsCondition = ref<DataRecordStatisticsConditionDto>();
      /**
       * 是否搜索后加载数据
       */
      const dataLoading = ref<boolean>(false);
      /**
       * 当前按钮对应sql的数据编辑标记，用于控制界面中当前显示的数据是否可进行编辑及对应的按钮
       */
      const currentSqlEditFlag = ref<number>(0);
      /**
       * 查询结果显示tab页的key
       */
      const activeTabKey = ref('1');

      //图标显示传值数据
      const chartComponentKey = ref<number>(0); //设置为图表组件的ID，用于点击查询按钮时对图表组件进行重新加载以达到图表刷新的效果
      const chartMinTime = ref<Date | undefined>();
      const chartMaxTime = ref<Date | undefined>();
      const chartTimeType = ref<String | undefined>();
      const chartYAxis = ref<ChartYAxisProps[]>();
      const chartSeries = ref<TimeSeriesProps[]>();

      const chartComponentKey2 = ref<number>(0); //设置为图表组件的ID，用于点击查询按钮时对图表组件进行重新加载以达到图表刷新的效果
      const chartMinTime2 = ref<Date | undefined>();
      const chartMaxTime2 = ref<Date | undefined>();
      const chartTimeType2 = ref<String | undefined>();
      const chartYAxis2 = ref<ChartYAxisProps[]>();
      const chartSeries2 = ref<TimeSeriesProps[]>();

      /**
       * 获取查询条件数据，用于生成通道--分类--站点选择列表
       */
      function initQueryConditionData(param1: string, param2: string) {
        //根据param1判断传入的是通道、数据分类还是站点编码
        let condition: ExchangeConfigQueryConditionDto = {};
        if (param1 === 'channel') {
          condition.channel = param2;
        } else if (param1 === 'category') {
          condition.category = param2;
        } else {
          condition.stcd = param2;
        }
        getQueryConditionData(condition)
          .then((res) => {
            console.log('getQueryConditionData res', res);
            //设置第1个站点为默认选中对象
            let defaultSelectValue = [];
            let defaultSelectStation: ExchangeStationDto;
            let options = [];
            allSqls.value = [];
            //每个节点的属性：value、label、children
            if (res != undefined && res != null) {
              if (res.channels != undefined && res.channels != null && res.channels.length > 0x0) {
                res.channels.forEach((channel) => {
                  let chl = {
                    label: channel.channel.name,
                    value: channel.channel.id,
                  };
                  //判断通道中是否有分类
                  if (
                    channel.categories != undefined &&
                    channel.categories != null &&
                    channel.categories.length > 0x0
                  ) {
                    categoriesData.value = channel.categories;
                    chl.children = [];
                    // 获取所有的查询方法
                    let querySqls = [];
                    channel.categories.forEach((category) => {
                      console.log('category.sqls', category.sqls);
                      if (
                        category.sqls != undefined &&
                        category.sqls != null &&
                        category.sqls.length > 0x0
                      ) {
                        category.sqls.forEach((sqlObj) => {
                          if (sqlObj.optype === 0 || sqlObj.optype === '0') querySqls.push(sqlObj);
                        });
                      }

                      let cat = {
                        label: category.category.name,
                        value: category.category.id,
                      };
                      if (
                        category.stations != undefined &&
                        category.stations != null &&
                        category.stations.length > 0x0
                      ) {
                        cat.children = [];
                        category.stations.forEach((station) => {
                          if (defaultSelectValue.length < 0x1) {
                            defaultSelectValue.push([chl.value, cat.value, station.stcd]);
                            defaultSelectStation = { ...station };
                          }
                          cat.children.push({
                            label: station.stnm,
                            value: station.stcd,
                            params: station.params,
                          });
                        });
                      } else {
                        //在交换数据通道、分类均有值，但站点集合为空时；设置默认选中的通道和分类，避免出现后面提示信息不准的问题
                        if (defaultSelectValue.length < 0x1)
                          defaultSelectValue.push([chl.value, cat.value, '']); //设置选中的站点编码为空
                      }
                      chl.children.push(cat);
                    });
                    // 保存第一个查询方法
                    console.log('querySqls', querySqls);
                    defaultQuerySql.value = querySqls[0];
                  }
                  options.push(chl);
                });
              }
              if (res.sqls.length > 0x0) {
                allSqls.value = res.sqls;
              }
            }
            stcdOptions.value = options;
            console.log('getQueryConditionData stcdOptions', options);
            stcd.value = defaultSelectValue;
            //获取选中站点对象信息设置数据统计条件
            setStatisticsCondition(defaultSelectStation);

            // 页面加载完成后默认加载第一个查询方法
            onExchangeDataQueryButtonClick(defaultQuerySql.value);
          })
          .catch((ex) => {
            console.log('getQueryConditionData ex', ex);
          });
        console.log(categoriesData, 'categ');
      }

      /**
       * 交换数据查询按钮点击事件
       */
      async function onExchangeDataQueryButtonClick(
        sql: DBTableSqlSimpleDto | undefined,
        isOnlyStatics = false,
      ) {
        console.log('sql', sql);
        //出现loading
        dataLoading.value = true;
        if (sql === undefined || sql === null) {
          //没有sql对象信息，提示错误
          createErrorModal({
            title: t('sys.api.errorTip'),
            content: '配置错误，当前数据分类没有配置有效的SQL语句。',
            getContainer: () => document.body,
          });

          return;
        }
        currentSqlEditFlag.value = sql.editflag;
        //使用级联选择对象后会出现只有1个3级对象选中时级联选择框的值为第2级对象，只有1个2级对象选中时值为第1级对象
        //如：[ [ 2, 3, "5301000101" ] ]获取选中值为：[ [ 2 ] ]
        let condition: ExchangeDataQueryConditionDto = {
          cid: 0,
          sql: sql.code,
          stcd: '',
          btm: 'string',
          etm: 'string',
          asc: true,
          isOnlyStatics: isOnlyStatics,
          // sts: '',//接口中定义类型为object，赋值为string会导致400 BAD_REQUEST
        };

        //解析级联选择中的值，获取cid和stcd；暂时按照只有1个站点考虑，多个站点时需要统一在1个数据分类下，否则无法根据查询按钮指定
        //如果级联选择中的值只有1个或2个，表示后面的均为选中状态，需要从查询条件获取中得到的通道--分类--站点信息中自动获取后设置cid和stcd
        let selectStcds = stcd.value;
        let firstSelectStcd = selectStcds[0x0];
        console.log('tmrange', tmrange.value);
        console.log('raw stcd', stcd.value);
        //取值时需要根据是否支持多选，得到的结果不同
        //设置为不能多选时，初始选中第1个赋值为：[ [ 1, 1, "53010002" ] ]；人工操作选中1个赋值为：[ 1, 2, "53010002" ]
        //判断获取级联选择的值数组第1个，如果为数组则按数组方式获取，如果不为数组按对象方式获取--直接使用stcd作为数组进行获取
        if (!Array.isArray(firstSelectStcd)) {
          firstSelectStcd = selectStcds;
        }
        console.log('firstSelectStcd', firstSelectStcd);
        if (Array.isArray(firstSelectStcd)) {
          if (firstSelectStcd.length === 0x3) {
            condition.cid = firstSelectStcd[0x1];
            condition.stcd = firstSelectStcd[0x2];
          } else if (firstSelectStcd.length === 0x2) {
            condition.cid = firstSelectStcd[0x1];
            let dataOptions = stcdOptions.value;
            //记录通道和分类所在的索引
            let channelIndex = -1;
            let categoryIndex = -1;
            for (let i = 0; i < dataOptions?.length; i++) {
              if (channelIndex >= 0x0 && categoryIndex >= 0x0) break;
              const channel = dataOptions[i];
              for (let j = 0; j < channel.children?.length; j++) {
                const categories = channel.children[j];
                if (categories.value === condition.cid) {
                  channelIndex = i;
                  categoryIndex = j;
                  break;
                }
              }
            }
            let stations = dataOptions[channelIndex].children[categoryIndex].children;
            //获取该分类下的所有站点编码，逗号分隔
            if (stations != undefined && stations != null && stations.length > 0x0) {
              stations.forEach((element) => {
                condition.stcd += element.value + ',';
              });
            }
          } else if (firstSelectStcd.length === 0x1) {
            let selectChannelId = firstSelectStcd[0x0];
            let dataOptions = stcdOptions.value;
            //记录通道所在的索引
            let channelIndex = -1;
            for (let i = 0; i < dataOptions?.length; i++) {
              const channel = dataOptions[i];
              if (channel.value === selectChannelId) {
                channelIndex = i;
                break;
              }
            }
            //根据通道ID获取分类和分类下的所有站点编码
            let categories = dataOptions[channelIndex].children;
            //获取该分类下的所有站点编码，逗号分隔
            if (categories != undefined && categories != null && categories.length > 0x0) {
              condition.cid = categories[0x0].value;
              categories.forEach((cat) => {
                if (
                  cat.children != undefined &&
                  cat.children != null &&
                  cat.children.length > 0x0
                ) {
                  cat.children.forEach((sta) => {
                    condition.stcd += sta.value + ',';
                  });
                }
              });
            }
          }
        }
        //解析选中的时间段
        let selectTm = tmrange.value;
        if (selectTm.length >= 0x2) {
          condition.btm = selectTm[0x0].format('YYYY-MM-DD HH:mm:ss');
          condition.etm = selectTm[0x1].format('YYYY-MM-DD HH:mm:ss');
        }
        condition.sts = statisticsCondition.value;

        // 获取对应表格标题
        console.log('分类id', condition.cid);
        if (
          categoriesData.value != undefined &&
          categoriesData.value != null &&
          categoriesData.value.length > 0x0
        ) {
          categoriesData.value.forEach((category) => {
            if (condition.cid === category.category.id) {
              // 获取cid对应的名称 --- 表格标题
              moduleTitle.value = category.category.name;
            }
          });
        }
        //查询前对变量进行重置赋值--表格列、编辑表单列、数据
        let showInTableColumns = [];
        let showInEditFormColumns = [];
        let rowData = [];
        let stationCodes: String[] = []; //站点编码集合
        let stationNames: String[] = []; //站点名称集合

        //查询前对传给图表组件的属性清空或重置
        //清空图表组件key的值，设置为0
        chartComponentKey.value = 0;
        let dataColumnAsYAxis: ChartYAxisProps[] = []; //数据值列作为图表Y轴序列
        let series: TimeSeriesProps[] = []; //图表数据序列集合
        let tmColumnCode: String = ''; //时间列的字段名称
        let stcdColumnCode: String = ''; //站点列的字段名称
        //查询交换数据--返回原始数据
        await queryExchangeDataAsRawData(condition)
          .then((res) => {
            console.log('queryExchangeDataAsRawData res', res);
            dataLoading.value = false;
            if (!res) {
              //查询返回的结果为空，可能是查询条件不正确或者后台处理错误
            } else {
              statisticsResult.value = res.sts;
              // 如果只返回了统计结果,只做上面的统计值赋值处理并跳转到数据统计tab就可以
              if (isOnlyStatics) {
                activeTabKey.value = '3';
                return;
              }
              //获取查询条件中的起止时间，图表显示中的起止时间短显示控制
              chartMinTime.value = new Date(condition.btm);
              chartMaxTime.value = new Date(condition.etm);
              //测试赋值，时间类型
              chartTimeType.value = 'minute';
              //判断查询返回结果中的站点集合
              if (res.stations != undefined && res.stations != null && res.stations.length > 0x0) {
                res.stations.forEach((station) => {
                  stationCodes.push(station.stcd);
                  stationNames.push(station.stnm);
                });
              }
              //判断查询返回结果中的列集合
              if (res.columns != undefined && res.columns != null && res.columns.length > 0x0) {
                //调用查询数据接口后，根据返回信息中的列集合更新表格显示列信息和编辑表单列信息
                res.columns.forEach((columnDto) => {
                  // console.log('columnDto====', columnDto);
                  //记录时间列和站点编码对应的字段名称，方便后面获取数据
                  if (columnDto.coltype === 32 || columnDto.coltype === '32')
                    tmColumnCode = columnDto.code;
                  else if (columnDto.coltype === 20 || columnDto.coltype === '20')
                    stcdColumnCode = columnDto.code;
                  //列在表格中是否显示，默认为true--要显示
                  if (
                    columnDto.qrshow != undefined &&
                    columnDto.qrshow != null &&
                    columnDto.qrshow === false
                  )
                    console.log('columnDto =在表格中不显示，columnDto' + columnDto);
                  else {
                    //要在表格中显示，设置显示的标题、固定、格式化等
                    showInTableColumns.push(getBasicColumnByColumnDto(columnDto));
                  }
                  //在编辑表单中显示标记为true
                  if (columnDto.efshow === true) {
                    showInEditFormColumns.push(columnDto);
                  }
                  //判断如果列类型是数据值，加入到图表的Y轴序列中
                  if (columnDto.coltype === 40 || columnDto.coltype === '40') {
                    let yData: ChartYAxisProps = {
                      //先将Y轴的id设置为列编码，如果在图表json中有指定id再覆盖
                      id: columnDto.code,
                      field: columnDto.code,
                      name: columnDto.name,
                      unit: '', //默认为没有单位，设置为空字符串
                      type: 'value', //Y轴类型固定为数值
                      position: 'left', //固定在左边
                      inverse: false, //固定从下往上，不反转
                      seriesType: 'line', //默认为折线图
                      show: true, //初始状态下显示
                    };
                    //图表中Y轴和数据值的单位
                    if (
                      columnDto.unit != undefined &&
                      columnDto.unit != null &&
                      columnDto.unit != ''
                    )
                      yData.unit = columnDto.unit;
                    //获取列信息中的图表配置属性，根据属性进行赋值
                    //此处需要赋值的属性有：数据序列的类型（折线图/柱状图)、最值、最小间隔、左右位置、是否上下反转
                    if (
                      columnDto.qrcharts != undefined &&
                      columnDto.qrcharts != null &&
                      columnDto.qrcharts != ''
                    ) {
                      console.log(
                        'columnDto code=' + columnDto.code + ' qrcharts=' + columnDto.qrcharts,
                      );
                      //转换为json对象，获取json对象中的属性值
                      let columnChartJsonObject;
                      try {
                        columnChartJsonObject = JSON.parse(columnDto.qrcharts);
                      } catch (e) {
                        //图表显示json解析异常，json字符串格式不正确，弹出提示
                        notification.warn({
                          message: t('sys.api.errorTip'),
                          description:
                            '处理数据值列：' +
                            columnDto.name +
                            '时图表配置json字符串：' +
                            columnDto.qrcharts +
                            '错误，无法解析为正确的json对象。',
                        });
                      }
                      if (columnChartJsonObject != undefined && columnChartJsonObject != null) {
                        //图表中使用该Y轴的序列的类型，决定使用该Y轴的序列是折线图还是柱状图
                        if (
                          columnChartJsonObject.type !== undefined &&
                          columnChartJsonObject.type !== null &&
                          columnChartJsonObject.type !== ''
                        )
                          yData.seriesType = columnChartJsonObject.type;
                        //初始状态下是否显示
                        if (
                          columnChartJsonObject.show !== undefined &&
                          columnChartJsonObject.show !== null &&
                          columnChartJsonObject.show === false
                        )
                          yData.show = false;
                        //Y轴是否反转，数值从小到大是自上而下还是自下而上
                        if (
                          columnChartJsonObject.inverse !== undefined &&
                          columnChartJsonObject.inverse !== null &&
                          columnChartJsonObject.inverse !== ''
                        )
                          yData.inverse = columnChartJsonObject.inverse;
                        //如果图表json中有指定id，覆盖Y轴的id属性
                        if (
                          columnChartJsonObject.id !== undefined &&
                          columnChartJsonObject.id !== null &&
                          columnChartJsonObject.id != ''
                        )
                          yData.id = columnChartJsonObject.id;
                        //Y轴的最小值和最大值处理：需要同时根据设置的Y轴最值放大系数和指定的最值进行判断处理
                        /**
                         * Y轴的最值处理逻辑：
                         * 0.如果有直接指定min或max属性，设置Y轴的min和max--如果使用json配置中的指定最小或最大值，可能造成控制显示半区无效；因此先使用最值属性值进行设置，后面进行覆盖
                         * 1.判断控制显示位置属性，bottom表示在下半区、top表示在上半区
                         * 2.根据Y轴的最值放大系数，计算并设置Y轴的最大值
                         *    需要依据的属性有：inverse、position、modulus、min
                         */
                        if (
                          columnChartJsonObject.direction !== undefined &&
                          columnChartJsonObject.direction !== null &&
                          columnChartJsonObject.direction != ''
                        ) {
                          //先使用属性值中的最小值和最大值进行赋值，后面判断如果有控制显示位置属性再对最值进行覆盖
                          if (
                            columnChartJsonObject.min !== undefined &&
                            columnChartJsonObject.min !== null &&
                            columnChartJsonObject.min !== ''
                          )
                            //如果是直接指定的最小值，使用指定值
                            yData.min = columnChartJsonObject.min;
                          if (
                            columnChartJsonObject.max !== undefined &&
                            columnChartJsonObject.max !== null &&
                            columnChartJsonObject.max !== ''
                          )
                            yData.max = columnChartJsonObject.max;
                          //获取放大系数，默认为放大2倍，至少保证各占1/2
                          let modulus = 2.0;
                          if (
                            columnChartJsonObject.modulus !== undefined &&
                            columnChartJsonObject.modulus !== null &&
                            columnChartJsonObject.modulus !== ''
                          )
                            modulus = columnChartJsonObject.modulus;
                          //获取序列中的数据值，包含最小、最大、差值
                          let seriesMinValue: Number;
                          let seriesMaxValue: Number;
                          //指定定义的变量类型为Number，使用 Number.isNaN(seriesMinValue)判断结果仍为false
                          if (res.data != undefined && res.data != null) {
                            res.data.forEach((datarow) => {
                              let rowDataValue = datarow[columnDto.code];
                              if (
                                rowDataValue != undefined &&
                                rowDataValue != null &&
                                rowDataValue != ''
                              ) {
                                //数值转换为Number进行大小判断
                                let dataValue = Number(rowDataValue);
                                // console.log('res.data.forEach dataValue=' + dataValue);
                                if (Number.isNaN(dataValue) === false) {
                                  if (
                                    Number.isNaN(Number(seriesMinValue)) === true ||
                                    seriesMinValue > dataValue
                                  )
                                    seriesMinValue = dataValue;
                                  if (
                                    Number.isNaN(Number(seriesMaxValue)) === true ||
                                    seriesMaxValue < dataValue
                                  )
                                    seriesMaxValue = dataValue;
                                }
                              }
                            });
                          }
                          if (
                            Number.isNaN(Number(seriesMinValue)) === false &&
                            Number.isNaN(Number(seriesMaxValue)) === false
                          ) {
                            //必须要有根据数据序列得到的最小值和最大值才能进行显示位置分区控制
                            let seriesDiffValue = seriesMaxValue - seriesMinValue;
                            /**
                             * 控制方式1：通过设置Y轴的最小值：设置为比数据序列中的最小值还小
                             *        适用情况及显示效果：1.Y轴坐标系没有反转，要控制显示在上半区；2.Y轴坐标系反转，要控制显示在下半区
                             *        控制处理逻辑：设置Y轴的最小值=序列最小数值+（序列最大数值-序列最小数值）*放大系数
                             *                    控制显示要设置Y轴的min属性，因此在json配置中指定了min属性值需要进行覆盖；json配置中指定了max属性不进行处理，设置不合理会造成超过最大值的无法显示；
                             *
                             * 控制方式2：通过设置Y轴的最大值：设置为比数据序列中的最大值还大
                             *        使用情况及显示效果：1.Y轴坐标系没有反转，要控制显示在下半区；2.Y轴坐标系反转，要控制显示在上半区
                             *        控制处理逻辑：如果设置最小值，设置Y轴的最大值=序列最大数值+（序列最大数值-Y轴最小值）*放大系数
                             *                    如果未设置最小值，设置Y轴的最大值=序列最大数值+（序列最大数值-序列最小数值）*放大系数
                             *                    控制显示要设置Y轴的max属性，因此在json配置中指定了max属性值需要进行覆盖；json配置中指定了min属性不进行处理，设置不合理会造成小于最小值的无法显示；
                             */
                            let setYAxisMin = true; //根据控制显示的上下半区位置和Y轴坐标系是否反转得到是要设置Y轴的最小值还是最大值
                            //如果Y轴坐标系反转，控制显示在上半区要设置最大值属性
                            //如果Y轴坐标系没有反转，控制显示在下半区要设置最大值属性
                            if (
                              yData.inverse === true &&
                              (columnChartJsonObject.direction === 'top' ||
                                columnChartJsonObject.direction === 'TOP')
                            )
                              setYAxisMin = false;
                            if (
                              yData.inverse === false &&
                              (columnChartJsonObject.direction === 'bottom' ||
                                columnChartJsonObject.direction === 'BOTTOM')
                            )
                              setYAxisMin = false;
                            if (setYAxisMin === true) {
                              //需要通过设置最小值来控制；可能是未反转的显示在上半区、反转的显示在下半区
                              //如果数据序列的差值为0，使用数据序列的最小值为放大系数的基值
                              let yaxisMinValue =
                                seriesMinValue -
                                (seriesDiffValue > 0 ? seriesDiffValue : seriesMinValue) * modulus;
                              yData.min = numberFormatToString(
                                yaxisMinValue,
                                columnChartJsonObject.format,
                              );
                              //设置最小值后，如果y轴的最大值未设置，设置为序列数据中的最大值
                              //如果没有指定Y轴的最大值，强制指定Y轴最大值为序列数据的最大值以保证图表的数值范围区间均能正常显示出来
                              // if (yData.max === undefined || yData.max === null)
                              //   yData.max = numberFormatToString(
                              //     seriesMaxValue,
                              //     columnChartJsonObject.format,
                              //   );
                            } else {
                              //需要通过设置最大值来控制；可能是未反转的显示在下半区、反转的显示在上半区
                              //如果数据序列的差值为0，使用数据序列的最小值为放大系数的基值
                              let yaxisMaxValue =
                                seriesMaxValue +
                                (seriesDiffValue > 0 ? seriesDiffValue : seriesMinValue) * modulus;
                              //如果设置了Y轴最小值，还需要再计算的最大值基础上加上序列数据最小值与Y轴最小值的差值
                              if (
                                columnChartJsonObject.min !== undefined &&
                                columnChartJsonObject.min !== null &&
                                columnChartJsonObject.min !== '' &&
                                columnChartJsonObject.min !== 0
                              ) {
                                yaxisMaxValue =
                                  yaxisMaxValue + (seriesMinValue - columnChartJsonObject.min);
                              }
                              //避免Y轴刻度中的数字显示多位小数，在此进行格式输出
                              yData.max = numberFormatToString(
                                yaxisMaxValue,
                                columnChartJsonObject.format,
                              );
                              //设置最大值后，如果y轴的最小值未设置，设置为序列数据中的最小值
                              //如果没有指定Y轴的最小值，强制指定Y轴最小值为序列数据的最小值以保证图表的数值范围区间均能正常显示出来
                              // if (yData.min === undefined || yData.min === null)
                              //   yData.min = numberFormatToString(
                              //     seriesMinValue,
                              //     columnChartJsonObject.format,
                              //   );
                            }

                            console.log(
                              '控制显示Y轴的上下半区，columnDto.name=' +
                                columnDto.name +
                                ' yData.inverse=' +
                                yData.inverse +
                                ' columnChartJsonObject.direction=' +
                                columnChartJsonObject.direction +
                                ' setYAxisMin=' +
                                setYAxisMin +
                                ' seriesMinValue=' +
                                seriesMinValue +
                                ' seriesMaxValue=' +
                                seriesMaxValue +
                                ' seriesDiffValue=' +
                                seriesDiffValue +
                                ' yData.min=' +
                                yData.min +
                                ' yData.max=' +
                                yData.max,
                            );
                          }
                        }
                        //Y轴的最小间隔
                        if (
                          columnChartJsonObject.minInterval !== undefined &&
                          columnChartJsonObject.minInterval !== null &&
                          columnChartJsonObject.minInterval !== ''
                        )
                          yData.minInterval = columnChartJsonObject.minInterval;
                        //Y轴的左右位置，取值：left、right
                        if (
                          columnChartJsonObject.position != undefined &&
                          columnChartJsonObject.position != null &&
                          columnChartJsonObject.position != ''
                        )
                          yData.position = columnChartJsonObject.position;
                        //Y轴的显示位置偏移量，如果在一侧有多个Y轴需要控制错开显示位置
                        if (
                          columnChartJsonObject.offset != undefined &&
                          columnChartJsonObject.offset != null &&
                          columnChartJsonObject.offset != ''
                        )
                          yData.offset = columnChartJsonObject.offset;
                        //Y轴数值格式化，格式化同时作用于Y轴坐标系和使用该Y轴的数据序列值显示
                        if (
                          columnChartJsonObject.format != undefined &&
                          columnChartJsonObject.format != null &&
                          columnChartJsonObject.format != ''
                        )
                          yData.format = columnChartJsonObject.format;
                        //判断数据库表列中是否有设置图表原生属性
                        if (
                          columnChartJsonObject.native != undefined &&
                          columnChartJsonObject.native != null &&
                          columnChartJsonObject.native != ''
                        )
                          yData.native = columnChartJsonObject.native;
                      }
                    }

                    dataColumnAsYAxis.push(yData);
                  }
                });
              }
              //查询结果数据行赋值给表格处理：直接赋值，不用判断是否为空、是否有数据
              //直接赋值在data为null时导致界面中的表格不刷新，显示的是上一次的数据
              // rowData = res.data;
              if (res.data !== undefined && res.data !== null) rowData = res.data;
              //查询数据行赋值给图表处理：如果查询结果中的数据行不为空，获取对应行的时间和数据值进行赋值
              if (res.data != undefined && res.data != null && res.data.length > 0x0) {
                //表格数据赋值，放在此处判断data不为null
                rowData = res.data;
                //如果站点名称集合和Y轴集合不为空，进行图表序列数据处理；
                if (
                  stationCodes.length > 0x0 &&
                  stationNames.length > 0x0 &&
                  dataColumnAsYAxis.length > 0x0
                ) {
                  stationNames.forEach((stnm, stationIndex) => {
                    dataColumnAsYAxis.forEach((yaxis, yAxisIndex) => {
                      let seriesData: TimeSeriesProps = {
                        type: yaxis.seriesType, //同Y轴中的图表类型属性
                        show: yaxis.show, //初始状态下该序列数据图表是否显示
                        name: stationNames.length > 0x1 ? stnm + ' ' + yaxis.name : yaxis.name, //序列名称：站点名称+数据类型（Y轴名称/列名）
                        objectIndex: stationIndex,
                        yAxisIndex: yAxisIndex,
                        data: [], //初始化为空，后面遍历行添加
                      };
                      //判断是否有原始属性
                      if (yaxis.native != undefined && yaxis.native != null && yaxis.native != '')
                        seriesData.native = yaxis.native;
                      //将数据序列加入集合，此时数据序列的data为空
                      series.push(seriesData);
                    });
                  });
                  res.data.forEach((datarow) => {
                    //获取时间列
                    let rowDataTimeObject = datarow[tmColumnCode];
                    if (
                      rowDataTimeObject != undefined &&
                      rowDataTimeObject != null &&
                      rowDataTimeObject != ''
                    ) {
                      //时间转为Date类型
                      let rowDataTime = new Date(rowDataTimeObject);
                      //如果有多个站点，逐个遍历列集合设置使用的Y轴索引；需要计算当前站点的索引，如果只有1个站点固定站点索引为0
                      //根据站点编码获取在站点编码集合中的索引序号，方便使用索引序号获取对应的数据序列使用
                      let stationIndex: number = 0;
                      //如果有多个站点，判断后进行计算当前站点的索引序号
                      if (stationCodes.length > 0x1) {
                        //站点ID/编码列名称不能为空
                        if (
                          stcdColumnCode != undefined &&
                          stcdColumnCode != null &&
                          stcdColumnCode != ''
                        ) {
                          let rowDataStcd = datarow[stcdColumnCode];
                          if (
                            rowDataStcd != undefined &&
                            rowDataStcd != null &&
                            rowDataStcd != ''
                          ) {
                            for (let i = 0; i < stationCodes.length; i++) {
                              if (rowDataStcd === stcd) {
                                stationIndex = idx;
                                break;
                              }
                            }
                          }
                        }
                      }

                      //遍历Y轴集合，获取对应的列名称，从数据行中获取数据并对data集合进行添加
                      dataColumnAsYAxis.forEach((yaxis, yAxisIndex) => {
                        //计算所对应数据序列的索引，计算方法为：站点索引*Y轴总数+当前Y轴索引
                        let dataSeriesIndex = stationIndex * dataColumnAsYAxis.length + yAxisIndex;
                        //根据列名获取对应行列的原始数据
                        //ChartYAxisProps中id表示自定义Y轴的id，使用field记录对应的列名称，修改为使用field获取对应列数据
                        // let rowDataValue = datarow[yaxis.id];
                        let rowDataValue = datarow[yaxis.field];
                        //数据值在此做转换和格式化处理，在图表组件中对数据值和时间进行统一格式化处理，此处不需要转换为数值和格式化处理
                        // series[dataSeriesIndex].data.push([
                        //   rowDataTime,
                        //   numberFormatToString(rowDataValue),
                        // ]);
                        series[dataSeriesIndex].data.push([rowDataTime, rowDataValue]);
                      });
                    }
                  });
                }
              }
            }

            // 表格增加column操作列渲染编辑按钮;
            if (
              (currentSqlEditFlag.value & 0x2) === 0x2 ||
              (currentSqlEditFlag.value & 0x4) === 0x4
            ) {
              if (showInTableColumns != null && showInTableColumns.length > 0x0) {
                let tablecolumn = {
                  title: '操作',
                  dataIndex: 'actions',
                  fixed: 'right',
                  customRender: ({ record }) => {
                    // 渲染操作列显示结果
                    // console.log('record', record);
                    let result = ''; //返回结果
                    let isEdit = (currentSqlEditFlag.value & 0x2) === 0x2; //是否显示编辑按钮
                    let isDelete = (currentSqlEditFlag.value & 0x4) === 0x4; //是否显示删除按钮

                    if (isEdit === true) {
                      if (isDelete === true) {
                        result = h('span', [
                          h(Tooltip, { title: '编辑' }, () => [
                            h(
                              Button,
                              {
                                type: 'primary',
                                size: 'small',
                                onClick: onExchangeDataEditButtonClick.bind(null, record),
                              },
                              () => [h(EditOutlined, { cursor: 'pointer' })],
                            ),
                          ]),
                          h(Tooltip, { title: '删除' }, () => [
                            h(
                              Button,
                              {
                                type: 'error',
                                size: 'small',
                                // onClick: onExchangeDataEditButtonClick.bind(null, record),
                              },
                              () => [h(DeleteOutlined, { cursor: 'pointer' })],
                            ),
                          ]),
                        ]);
                      } else {
                        //只有修改，没有删除
                        result = h(Tooltip, { title: '编辑' }, () => [
                          h(
                            Button,
                            {
                              type: 'primary',
                              size: 'small',
                              onClick: onExchangeDataEditButtonClick.bind(null, record),
                            },
                            () => [h(EditOutlined, { cursor: 'pointer' })],
                          ),
                        ]);
                      }
                    } else {
                      //没有修改
                      if (isDelete === true) {
                        result = h(Tooltip, { title: '删除' }, () => [
                          h(
                            Button,
                            {
                              type: 'error',
                              size: 'small',
                              // onClick: onExchangeDataEditButtonClick.bind(null, record),
                            },
                            () => [h(DeleteOutlined, { cursor: 'pointer' })],
                          ),
                        ]);
                      }
                    }
                    return result;
                  },
                };
                showInTableColumns.push(tablecolumn);
              }
            }
          })
          .catch((ex) => {
            dataLoading.value = false;
            console.log('queryExchangeDataAsRawData ex', ex);
          });

        //如果只是进行数据统计，不需要对表格、图表数据进行赋值和更新
        if (isOnlyStatics) {
          return;
        }
        console.log('onExchangeDataQueryButtonClick showInTableColumns', showInTableColumns);
        console.log('onExchangeDataQueryButtonClick rowData', rowData);
        console.log('onExchangeDataQueryButtonClick series', series);

        //设置表格数据
        tableColumns.value = showInTableColumns;
        editFormColumns.value = showInEditFormColumns;
        totalData.value = rowData;
        endIndex.value = 100;
        tableData.value = rowData.slice(0, endIndex.value);
        let dom = document.querySelector('.ant-table-body');
        dom.scrollTop = 0;
        //设置图表数据
        chartYAxis.value = dataColumnAsYAxis;
        chartSeries.value = series;
        chartComponentKey.value = condition.cid;
      }

      function onOpenTimeStsConditionModalClick() {
        let propsData: QcUnifyTransToChildProps = {
          moduleName: '交换数据查询',
          operateString: '设置统计条件',
        };
        openTimeStsFormModal(true, propsData);
      }

      /**
       * 查询时间段次统计
       */
      async function onExchangeTimeStsQueryButtonClick(tmstsCondition) {
        //出现loading
        dataLoading.value = true;
        let condition: ExchangeDataQueryConditionDto = {
          cid: 0,
          sql: 'queryAll',
          stcd: '',
          btm: 'string',
          etm: 'string',
          intervaltype: tmstsCondition.intervaltype,
          intlength: tmstsCondition.intlength,
          // sts: '',//接口中定义类型为object，赋值为string会导致400 BAD_REQUEST
        };

        //解析级联选择中的值，获取cid和stcd；暂时按照只有1个站点考虑，多个站点时需要统一在1个数据分类下，否则无法根据查询按钮指定
        //如果级联选择中的值只有1个或2个，表示后面的均为选中状态，需要从查询条件获取中得到的通道--分类--站点信息中自动获取后设置cid和stcd
        let selectStcds = stcd.value;
        let firstSelectStcd = selectStcds[0x0];
        //取值时需要根据是否支持多选，得到的结果不同
        //设置为不能多选时，初始选中第1个赋值为：[ [ 1, 1, "53010002" ] ]；人工操作选中1个赋值为：[ 1, 2, "53010002" ]
        //判断获取级联选择的值数组第1个，如果为数组则按数组方式获取，如果不为数组按对象方式获取--直接使用stcd作为数组进行获取
        if (!Array.isArray(firstSelectStcd)) {
          firstSelectStcd = selectStcds;
        }
        if (Array.isArray(firstSelectStcd)) {
          if (firstSelectStcd.length === 0x3) {
            condition.cid = firstSelectStcd[0x1];
            condition.stcd = firstSelectStcd[0x2];
          } else if (firstSelectStcd.length === 0x2) {
            condition.cid = firstSelectStcd[0x1];
            let dataOptions = stcdOptions.value;
            //记录通道和分类所在的索引
            let channelIndex = -1;
            let categoryIndex = -1;
            for (let i = 0; i < dataOptions?.length; i++) {
              if (channelIndex >= 0x0 && categoryIndex >= 0x0) break;
              const channel = dataOptions[i];
              for (let j = 0; j < channel.children?.length; j++) {
                const categories = channel.children[j];
                if (categories.value === condition.cid) {
                  channelIndex = i;
                  categoryIndex = j;
                  break;
                }
              }
            }
            let stations = dataOptions[channelIndex].children[categoryIndex].children;
            //获取该分类下的所有站点编码，逗号分隔
            if (stations != undefined && stations != null && stations.length > 0x0) {
              stations.forEach((element) => {
                condition.stcd += element.value + ',';
              });
            }
          } else if (firstSelectStcd.length === 0x1) {
            let selectChannelId = firstSelectStcd[0x0];
            let dataOptions = stcdOptions.value;
            //记录通道所在的索引
            let channelIndex = -1;
            for (let i = 0; i < dataOptions?.length; i++) {
              const channel = dataOptions[i];
              if (channel.value === selectChannelId) {
                channelIndex = i;
                break;
              }
            }
            //根据通道ID获取分类和分类下的所有站点编码
            let categories = dataOptions[channelIndex].children;
            //获取该分类下的所有站点编码，逗号分隔
            if (categories != undefined && categories != null && categories.length > 0x0) {
              condition.cid = categories[0x0].value;
              categories.forEach((cat) => {
                if (
                  cat.children != undefined &&
                  cat.children != null &&
                  cat.children.length > 0x0
                ) {
                  cat.children.forEach((sta) => {
                    condition.stcd += sta.value + ',';
                  });
                }
              });
            }
          }
        }
        //解析选中的时间段
        let selectTm = tmrange.value;
        if (selectTm.length >= 0x2) {
          condition.btm = selectTm[0x0].format('YYYY-MM-DD HH:mm:ss');
          condition.etm = selectTm[0x1].format('YYYY-MM-DD HH:mm:ss');
        }

        // 获取对应表格标题
        console.log('分类id', condition.cid);
        if (
          categoriesData.value != undefined &&
          categoriesData.value != null &&
          categoriesData.value.length > 0x0
        ) {
          categoriesData.value.forEach((category) => {
            if (condition.cid === category.category.id) {
              // 获取cid对应的名称 --- 表格标题
              moduleTitle.value = category.category.name;
            }
          });
        }
        //查询前对变量进行重置赋值--表格列、编辑表单列、数据
        let showInTableColumns = [];
        let showInEditFormColumns = [];
        let rowData = [];
        let stationCodes: String[] = []; //站点编码集合
        let stationNames: String[] = []; //站点名称集合

        //查询前对传给图表组件的属性清空或重置
        //清空图表组件key的值，设置为0
        chartComponentKey2.value = 0;
        let dataColumnAsYAxis: ChartYAxisProps[] = []; //数据值列作为图表Y轴序列
        let series: TimeSeriesProps[] = []; //图表数据序列集合
        let tmColumnCode: String = ''; //时间列的字段名称
        let stcdColumnCode: String = ''; //站点列的字段名称
        //查询交换数据--返回原始数据
        await regularByTime(condition)
          .then((res) => {
            dataLoading.value = false;
            if (!res) {
              //查询返回的结果为空，可能是查询条件不正确或者后台处理错误
            } else {
              tmstsResult.value = res;
              //获取查询条件中的起止时间，图表显示中的起止时间短显示控制
              chartMinTime2.value = new Date(condition.btm);
              chartMaxTime2.value = new Date(condition.etm);
              //测试赋值，时间类型
              chartTimeType2.value = 'minute';
              //判断查询返回结果中的站点集合
              if (res.stations != undefined && res.stations != null && res.stations.length > 0x0) {
                res.stations.forEach((station) => {
                  stationCodes.push(station.stcd);
                  stationNames.push(station.stnm);
                });
              }
              //判断查询返回结果中的列集合
              if (res.columns != undefined && res.columns != null && res.columns.length > 0x0) {
                //调用查询数据接口后，根据返回信息中的列集合更新表格显示列信息和编辑表单列信息
                res.columns.forEach((columnDto) => {
                  // console.log('columnDto====', columnDto);
                  //记录时间列和站点编码对应的字段名称，方便后面获取数据
                  if (columnDto.coltype === 32 || columnDto.coltype === '32')
                    tmColumnCode = columnDto.code;
                  else if (columnDto.coltype === 20 || columnDto.coltype === '20')
                    stcdColumnCode = columnDto.code;
                  //列在表格中是否显示，默认为true--要显示
                  if (
                    columnDto.qrshow != undefined &&
                    columnDto.qrshow != null &&
                    columnDto.qrshow === false
                  )
                    console.log('columnDto =在表格中不显示，columnDto' + columnDto);
                  else {
                    //要在表格中显示，设置显示的标题、固定、格式化等
                    showInTableColumns.push(getBasicColumnByColumnDto(columnDto));
                  }
                  //在编辑表单中显示标记为true
                  if (columnDto.efshow === true) {
                    showInEditFormColumns.push(columnDto);
                  }
                  //判断如果列类型是数据值，加入到图表的Y轴序列中
                  if (columnDto.coltype === 40 || columnDto.coltype === '40') {
                    let yData: ChartYAxisProps = {
                      //先将Y轴的id设置为列编码，如果在图表json中有指定id再覆盖
                      id: columnDto.code,
                      field: columnDto.code,
                      name: columnDto.name,
                      unit: '', //默认为没有单位，设置为空字符串
                      type: 'value', //Y轴类型固定为数值
                      position: 'left', //固定在左边
                      inverse: false, //固定从下往上，不反转
                      seriesType: 'line', //默认为折线图
                      show: true, //初始状态下显示
                    };
                    //图表中Y轴和数据值的单位
                    if (
                      columnDto.unit != undefined &&
                      columnDto.unit != null &&
                      columnDto.unit != ''
                    )
                      yData.unit = columnDto.unit;
                    //获取列信息中的图表配置属性，根据属性进行赋值
                    //此处需要赋值的属性有：数据序列的类型（折线图/柱状图)、最值、最小间隔、左右位置、是否上下反转
                    if (
                      columnDto.qrcharts != undefined &&
                      columnDto.qrcharts != null &&
                      columnDto.qrcharts != ''
                    ) {
                      console.log(
                        'columnDto code=' + columnDto.code + ' qrcharts=' + columnDto.qrcharts,
                      );
                      //转换为json对象，获取json对象中的属性值
                      let columnChartJsonObject;
                      try {
                        columnChartJsonObject = JSON.parse(columnDto.qrcharts);
                      } catch (e) {
                        //图表显示json解析异常，json字符串格式不正确，弹出提示
                        notification.warn({
                          message: t('sys.api.errorTip'),
                          description:
                            '处理数据值列：' +
                            columnDto.name +
                            '时图表配置json字符串：' +
                            columnDto.qrcharts +
                            '错误，无法解析为正确的json对象。',
                        });
                      }
                      if (columnChartJsonObject != undefined && columnChartJsonObject != null) {
                        //图表中使用该Y轴的序列的类型，决定使用该Y轴的序列是折线图还是柱状图
                        if (
                          columnChartJsonObject.type !== undefined &&
                          columnChartJsonObject.type !== null &&
                          columnChartJsonObject.type !== ''
                        )
                          yData.seriesType = columnChartJsonObject.type;
                        //初始状态下是否显示
                        if (
                          columnChartJsonObject.show !== undefined &&
                          columnChartJsonObject.show !== null &&
                          columnChartJsonObject.show === false
                        )
                          yData.show = false;
                        //Y轴是否反转，数值从小到大是自上而下还是自下而上
                        if (
                          columnChartJsonObject.inverse !== undefined &&
                          columnChartJsonObject.inverse !== null &&
                          columnChartJsonObject.inverse !== ''
                        )
                          yData.inverse = columnChartJsonObject.inverse;
                        //如果图表json中有指定id，覆盖Y轴的id属性
                        if (
                          columnChartJsonObject.id !== undefined &&
                          columnChartJsonObject.id !== null &&
                          columnChartJsonObject.id != ''
                        )
                          yData.id = columnChartJsonObject.id;
                        //Y轴的最小值和最大值处理：需要同时根据设置的Y轴最值放大系数和指定的最值进行判断处理
                        /**
                         * Y轴的最值处理逻辑：
                         * 0.如果有直接指定min或max属性，设置Y轴的min和max--如果使用json配置中的指定最小或最大值，可能造成控制显示半区无效；因此先使用最值属性值进行设置，后面进行覆盖
                         * 1.判断控制显示位置属性，bottom表示在下半区、top表示在上半区
                         * 2.根据Y轴的最值放大系数，计算并设置Y轴的最大值
                         *    需要依据的属性有：inverse、position、modulus、min
                         */
                        if (
                          columnChartJsonObject.direction !== undefined &&
                          columnChartJsonObject.direction !== null &&
                          columnChartJsonObject.direction != ''
                        ) {
                          //先使用属性值中的最小值和最大值进行赋值，后面判断如果有控制显示位置属性再对最值进行覆盖
                          if (
                            columnChartJsonObject.min !== undefined &&
                            columnChartJsonObject.min !== null &&
                            columnChartJsonObject.min !== ''
                          )
                            //如果是直接指定的最小值，使用指定值
                            yData.min = columnChartJsonObject.min;
                          if (
                            columnChartJsonObject.max !== undefined &&
                            columnChartJsonObject.max !== null &&
                            columnChartJsonObject.max !== ''
                          )
                            yData.max = columnChartJsonObject.max;
                          //获取放大系数，默认为放大2倍，至少保证各占1/2
                          let modulus = 2.0;
                          if (
                            columnChartJsonObject.modulus !== undefined &&
                            columnChartJsonObject.modulus !== null &&
                            columnChartJsonObject.modulus !== ''
                          )
                            modulus = columnChartJsonObject.modulus;
                          //获取序列中的数据值，包含最小、最大、差值
                          let seriesMinValue: Number;
                          let seriesMaxValue: Number;
                          //指定定义的变量类型为Number，使用 Number.isNaN(seriesMinValue)判断结果仍为false
                          if (res.data != undefined && res.data != null) {
                            res.data.forEach((datarow) => {
                              let rowDataValue = datarow[columnDto.code];
                              if (
                                rowDataValue != undefined &&
                                rowDataValue != null &&
                                rowDataValue != ''
                              ) {
                                //数值转换为Number进行大小判断
                                let dataValue = Number(rowDataValue);
                                // console.log('res.data.forEach dataValue=' + dataValue);
                                if (Number.isNaN(dataValue) === false) {
                                  if (
                                    Number.isNaN(Number(seriesMinValue)) === true ||
                                    seriesMinValue > dataValue
                                  )
                                    seriesMinValue = dataValue;
                                  if (
                                    Number.isNaN(Number(seriesMaxValue)) === true ||
                                    seriesMaxValue < dataValue
                                  )
                                    seriesMaxValue = dataValue;
                                }
                              }
                            });
                          }
                          if (
                            Number.isNaN(Number(seriesMinValue)) === false &&
                            Number.isNaN(Number(seriesMaxValue)) === false
                          ) {
                            //必须要有根据数据序列得到的最小值和最大值才能进行显示位置分区控制
                            let seriesDiffValue = seriesMaxValue - seriesMinValue;
                            /**
                             * 控制方式1：通过设置Y轴的最小值：设置为比数据序列中的最小值还小
                             *        适用情况及显示效果：1.Y轴坐标系没有反转，要控制显示在上半区；2.Y轴坐标系反转，要控制显示在下半区
                             *        控制处理逻辑：设置Y轴的最小值=序列最小数值+（序列最大数值-序列最小数值）*放大系数
                             *                    控制显示要设置Y轴的min属性，因此在json配置中指定了min属性值需要进行覆盖；json配置中指定了max属性不进行处理，设置不合理会造成超过最大值的无法显示；
                             *
                             * 控制方式2：通过设置Y轴的最大值：设置为比数据序列中的最大值还大
                             *        使用情况及显示效果：1.Y轴坐标系没有反转，要控制显示在下半区；2.Y轴坐标系反转，要控制显示在上半区
                             *        控制处理逻辑：如果设置最小值，设置Y轴的最大值=序列最大数值+（序列最大数值-Y轴最小值）*放大系数
                             *                    如果未设置最小值，设置Y轴的最大值=序列最大数值+（序列最大数值-序列最小数值）*放大系数
                             *                    控制显示要设置Y轴的max属性，因此在json配置中指定了max属性值需要进行覆盖；json配置中指定了min属性不进行处理，设置不合理会造成小于最小值的无法显示；
                             */
                            let setYAxisMin = true; //根据控制显示的上下半区位置和Y轴坐标系是否反转得到是要设置Y轴的最小值还是最大值
                            //如果Y轴坐标系反转，控制显示在上半区要设置最大值属性
                            //如果Y轴坐标系没有反转，控制显示在下半区要设置最大值属性
                            if (
                              yData.inverse === true &&
                              (columnChartJsonObject.direction === 'top' ||
                                columnChartJsonObject.direction === 'TOP')
                            )
                              setYAxisMin = false;
                            if (
                              yData.inverse === false &&
                              (columnChartJsonObject.direction === 'bottom' ||
                                columnChartJsonObject.direction === 'BOTTOM')
                            )
                              setYAxisMin = false;
                            if (setYAxisMin === true) {
                              //需要通过设置最小值来控制；可能是未反转的显示在上半区、反转的显示在下半区
                              //如果数据序列的差值为0，使用数据序列的最小值为放大系数的基值
                              let yaxisMinValue =
                                seriesMinValue -
                                (seriesDiffValue > 0 ? seriesDiffValue : seriesMinValue) * modulus;
                              yData.min = numberFormatToString(
                                yaxisMinValue,
                                columnChartJsonObject.format,
                              );
                              //设置最小值后，如果y轴的最大值未设置，设置为序列数据中的最大值
                              //如果没有指定Y轴的最大值，强制指定Y轴最大值为序列数据的最大值以保证图表的数值范围区间均能正常显示出来
                              // if (yData.max === undefined || yData.max === null)
                              //   yData.max = numberFormatToString(
                              //     seriesMaxValue,
                              //     columnChartJsonObject.format,
                              //   );
                            } else {
                              //需要通过设置最大值来控制；可能是未反转的显示在下半区、反转的显示在上半区
                              //如果数据序列的差值为0，使用数据序列的最小值为放大系数的基值
                              let yaxisMaxValue =
                                seriesMaxValue +
                                (seriesDiffValue > 0 ? seriesDiffValue : seriesMinValue) * modulus;
                              //如果设置了Y轴最小值，还需要再计算的最大值基础上加上序列数据最小值与Y轴最小值的差值
                              if (
                                columnChartJsonObject.min !== undefined &&
                                columnChartJsonObject.min !== null &&
                                columnChartJsonObject.min !== '' &&
                                columnChartJsonObject.min !== 0
                              ) {
                                yaxisMaxValue =
                                  yaxisMaxValue + (seriesMinValue - columnChartJsonObject.min);
                              }
                              //避免Y轴刻度中的数字显示多位小数，在此进行格式输出
                              yData.max = numberFormatToString(
                                yaxisMaxValue,
                                columnChartJsonObject.format,
                              );
                              //设置最大值后，如果y轴的最小值未设置，设置为序列数据中的最小值
                              //如果没有指定Y轴的最小值，强制指定Y轴最小值为序列数据的最小值以保证图表的数值范围区间均能正常显示出来
                              // if (yData.min === undefined || yData.min === null)
                              //   yData.min = numberFormatToString(
                              //     seriesMinValue,
                              //     columnChartJsonObject.format,
                              //   );
                            }
                          }
                        }
                        //Y轴的最小间隔
                        if (
                          columnChartJsonObject.minInterval !== undefined &&
                          columnChartJsonObject.minInterval !== null &&
                          columnChartJsonObject.minInterval !== ''
                        )
                          yData.minInterval = columnChartJsonObject.minInterval;
                        //Y轴的左右位置，取值：left、right
                        if (
                          columnChartJsonObject.position != undefined &&
                          columnChartJsonObject.position != null &&
                          columnChartJsonObject.position != ''
                        )
                          yData.position = columnChartJsonObject.position;
                        //Y轴的显示位置偏移量，如果在一侧有多个Y轴需要控制错开显示位置
                        if (
                          columnChartJsonObject.offset != undefined &&
                          columnChartJsonObject.offset != null &&
                          columnChartJsonObject.offset != ''
                        )
                          yData.offset = columnChartJsonObject.offset;
                        //Y轴数值格式化，格式化同时作用于Y轴坐标系和使用该Y轴的数据序列值显示
                        if (
                          columnChartJsonObject.format != undefined &&
                          columnChartJsonObject.format != null &&
                          columnChartJsonObject.format != ''
                        )
                          yData.format = columnChartJsonObject.format;
                        //判断数据库表列中是否有设置图表原生属性
                        if (
                          columnChartJsonObject.native != undefined &&
                          columnChartJsonObject.native != null &&
                          columnChartJsonObject.native != ''
                        )
                          yData.native = columnChartJsonObject.native;
                      }
                    }

                    dataColumnAsYAxis.push(yData);
                  }
                });
              }
              //查询结果数据行赋值给表格处理：直接赋值，不用判断是否为空、是否有数据
              //直接赋值在data为null时导致界面中的表格不刷新，显示的是上一次的数据
              // rowData = res.data;
              if (res.data !== undefined && res.data !== null) rowData = res.data;
              //查询数据行赋值给图表处理：如果查询结果中的数据行不为空，获取对应行的时间和数据值进行赋值
              if (res.data != undefined && res.data != null && res.data.length > 0x0) {
                //表格数据赋值，放在此处判断data不为null
                rowData = res.data;
                //如果站点名称集合和Y轴集合不为空，进行图表序列数据处理；
                if (
                  stationCodes.length > 0x0 &&
                  stationNames.length > 0x0 &&
                  dataColumnAsYAxis.length > 0x0
                ) {
                  stationNames.forEach((stnm, stationIndex) => {
                    dataColumnAsYAxis.forEach((yaxis, yAxisIndex) => {
                      let seriesData: TimeSeriesProps = {
                        type: yaxis.seriesType, //同Y轴中的图表类型属性
                        show: yaxis.show, //初始状态下该序列数据图表是否显示
                        name: stationNames.length > 0x1 ? stnm + ' ' + yaxis.name : yaxis.name, //序列名称：站点名称+数据类型（Y轴名称/列名）
                        objectIndex: stationIndex,
                        yAxisIndex: yAxisIndex,
                        data: [], //初始化为空，后面遍历行添加
                      };
                      //判断是否有原始属性
                      if (yaxis.native != undefined && yaxis.native != null && yaxis.native != '')
                        seriesData.native = yaxis.native;
                      //将数据序列加入集合，此时数据序列的data为空
                      series.push(seriesData);
                    });
                  });
                  res.data.forEach((datarow) => {
                    //获取时间列
                    let rowDataTimeObject = datarow[tmColumnCode];
                    if (
                      rowDataTimeObject != undefined &&
                      rowDataTimeObject != null &&
                      rowDataTimeObject != ''
                    ) {
                      //时间转为Date类型
                      let rowDataTime = new Date(rowDataTimeObject);
                      //如果有多个站点，逐个遍历列集合设置使用的Y轴索引；需要计算当前站点的索引，如果只有1个站点固定站点索引为0
                      //根据站点编码获取在站点编码集合中的索引序号，方便使用索引序号获取对应的数据序列使用
                      let stationIndex: number = 0;
                      //如果有多个站点，判断后进行计算当前站点的索引序号
                      if (stationCodes.length > 0x1) {
                        //站点ID/编码列名称不能为空
                        if (
                          stcdColumnCode != undefined &&
                          stcdColumnCode != null &&
                          stcdColumnCode != ''
                        ) {
                          let rowDataStcd = datarow[stcdColumnCode];
                          if (
                            rowDataStcd != undefined &&
                            rowDataStcd != null &&
                            rowDataStcd != ''
                          ) {
                            for (let i = 0; i < stationCodes.length; i++) {
                              if (rowDataStcd === stcd) {
                                stationIndex = idx;
                                break;
                              }
                            }
                          }
                        }
                      }

                      //遍历Y轴集合，获取对应的列名称，从数据行中获取数据并对data集合进行添加
                      dataColumnAsYAxis.forEach((yaxis, yAxisIndex) => {
                        //计算所对应数据序列的索引，计算方法为：站点索引*Y轴总数+当前Y轴索引
                        let dataSeriesIndex = stationIndex * dataColumnAsYAxis.length + yAxisIndex;
                        //根据列名获取对应行列的原始数据
                        //ChartYAxisProps中id表示自定义Y轴的id，使用field记录对应的列名称，修改为使用field获取对应列数据
                        // let rowDataValue = datarow[yaxis.id];
                        let rowDataValue = datarow[yaxis.field];
                        //数据值在此做转换和格式化处理，在图表组件中对数据值和时间进行统一格式化处理，此处不需要转换为数值和格式化处理
                        // series[dataSeriesIndex].data.push([
                        //   rowDataTime,
                        //   numberFormatToString(rowDataValue),
                        // ]);
                        series[dataSeriesIndex].data.push([rowDataTime, rowDataValue]);
                      });
                    }
                  });
                }
              }
            }
          })
          .catch((ex) => {
            dataLoading.value = false;
            console.log('queryExchangeDataAsRawData ex', ex);
          });
        //设置图表数据
        chartYAxis2.value = dataColumnAsYAxis;
        chartSeries2.value = series;
        chartComponentKey2.value = condition.cid;
      }
      /**
       * 新增交换数据按钮点击事件
       */
      function onExchangeDataAddButtonClick() {
        openCrudEditFormModal(OperationTypeEnum.ADD, null);
      }

      /**
       * 修改交换数据按钮点击事件
       */
      function onExchangeDataEditButtonClick(record: Recordable) {
        openCrudEditFormModal(OperationTypeEnum.EDIT, record);
      }

      /**
       * 打开通用的CRUD表单编辑Modal
       */
      function openCrudEditFormModal(operateType: OperationTypeEnum, data: any | undefined) {
        //先需要得到交换数据的查询条件中选择的交换数据分类ID、选中的对象ID
        //再根据交换数据分类ID获取对应列集合信息--用于生成表单Schema
        //根据选中的对象ID获取对象信息--用于传递给编辑组件中赋值给对象ID、对象名称和对象参数
        let categoryId = undefined; //交换数据分类ID
        let stationCode = ''; //交换站点ID
        let selectStcds = stcd.value;
        console.log('selectStcds', selectStcds);
        let firstSelectStcd = selectStcds[0x0];
        console.log('firstSelectStcd', firstSelectStcd);
        if (!Array.isArray(firstSelectStcd)) {
          firstSelectStcd = selectStcds;
        }
        if (Array.isArray(firstSelectStcd)) {
          if (firstSelectStcd.length === 0x3) {
            categoryId = firstSelectStcd[0x1];
            // 获取当前对象编码
            stationCode = firstSelectStcd[0x2];
          }
        }
        console.log('categoryId', categoryId);
        console.log('stationCode', stationCode);

        //获取交换数据分类信息，根据交换数据分类ID获取，方便获后面获取分类中的站点集合
        let category = undefined;
        //获取站点编码对应的站点名称和参数
        let stationName = undefined;
        let stationParma = undefined;
        if (
          categoriesData.value != undefined &&
          categoriesData.value != null &&
          categoriesData.value.length > 0x0
        ) {
          // console.log('categoriesData', categoriesData.value);
          categoriesData.value.forEach((categoryObj) => {
            // 获取当前对象的参数赋给编辑参数对象
            if (categoryId === categoryObj.category.id) {
              //找到交换数据分类ID的对象
              category = categoryObj;
              //再根据站点编码分类中的站点信息
              categoryObj.stations.forEach((stationObj) => {
                // console.log('stationObj', stationObj);
                if (stationCode === stationObj.stcd) {
                  stationName = stationObj.stnm;
                  stationParma = stationObj.params;
                }
              });
            }
          });
        }

        //根据操作类型，将数据库表列Dto转换为表单Schema对象
        let isAddOperate = operateType === OperationTypeEnum.ADD ? true : false;
        let schemas: FormSchema[] = [];
        editFormColumns.value.forEach((columnDto) => {
          //根据查询条件表单项获取转换对应的FormSchema对象
          let formItemSchema = getFormSchemaByColumn(columnDto, isAddOperate);
          //判断列类型，如果是对象ID、名称表示为选择的站点，需要对options进行赋值
          if (
            columnDto.coltype === 20 ||
            columnDto.coltype === '20' ||
            columnDto.coltype === 21 ||
            columnDto.coltype === '21'
          ) {
            // 设置站点选择项，默认选中第一个
            let selectOptions = [];
            if (category != undefined && category != null) {
              if (
                category.stations != undefined &&
                category.stations != null &&
                category.stations.length > 0x0
              ) {
                category.stations.forEach((station) => {
                  let option = {
                    label: station.stnm,
                    value:
                      columnDto.coltype === 20 || columnDto.coltype === '20'
                        ? station.stcd
                        : station.stnm, //如果存储的是对象ID设置value为站点编码，如果存储是的对象名称设置value为站点名称
                  };
                  selectOptions.push(option);
                });
              }
            }
            // console.log('selectOptions', selectOptions);
            formItemSchema.componentProps.options = selectOptions;
            formItemSchema.defaultVal = selectOptions[0].value;
          }
          schemas.push(formItemSchema);
        });

        //构造父组件给子组件传值对象
        let propsData: QcUnifyTransToChildProps = {
          moduleName: moduleTitle.value,
          operateType: OperationTypeEnum.ADD,
          formSchemas: schemas, //传编辑表单Scheme
          api: getSaveExchangeDataApiUrl(), //传交换数据保存接口地址
          //接口调用载荷对象使用payload传值给子组件
          payload: {
            cid: categoryId, //传当前交换数据分类ID
            objid: stationCode, //传站点ID、名称和参数信息
            objname: stationName,
            objparam: stationParma,
          },
        };
        //可选传递给子组件的对象：data--数据对象（修改时传入）、api--保存接口地址
        //如果是修改数据，对传值对象中的data进行赋值;
        //传编辑表单中赋值的数据对象，如果是新增不传值
        if (operateType === OperationTypeEnum.EDIT) {
          propsData.operateType = OperationTypeEnum.EDIT;
          propsData.data = data;
        }

        openSaveModal(true, propsData);
      }

      /**
       * 操作结束后刷新表格数据
       */
      function opSuccess() {
        onExchangeDataQueryButtonClick(defaultQuerySql.value);
      }
      /**
       * 点击统计条件弹窗的确认统计按钮
       */
      function onStatisticsConfirmButtonClick(data) {
        statisticsCondition.value = data;
        onExchangeDataQueryButtonClick(defaultQuerySql.value, true);
      }
      /**
       * 根据站点的params属性值设置数据统计条件
       */
      function setStatisticsCondition(stationObj: ExchangeStationDto | undefined) {
        let condition = { ...defaultExchangeStatisticsCondition };
        if (stationObj && stationObj.params && stationObj.params !== '') {
          console.log('setStatisticsCondition params', stationObj.params);
          // 解析string类型的数据格式为json
          let stationParamJson = {};
          try {
            stationParamJson = JSON.parse(stationObj.params);
          } catch (e) {
            //图表显示json解析异常，json字符串格式不正确，弹出提示
            notification.warn({
              message: t('sys.api.errorTip'),
              description:
                '处理站点：' +
                stationObj.stnm +
                '默认统计参数json：' +
                stationObj.params +
                '错误，无法解析为正确的json对象。',
            });
          }
          // 由于当params有值的时候,sts可能不存在,所以要再判断一层是否有sts
          if (stationParamJson.sts && stationParamJson.sts !== '') {
            if (
              stationParamJson.sts.ratetype != undefined &&
              stationParamJson.sts.ratetype != null &&
              stationParamJson.sts.ratetype != ''
            )
              condition.ratetype = Number(stationParamJson.sts.ratetype);
            if (
              stationParamJson.sts.ontimeafter != undefined &&
              stationParamJson.sts.ontimeafter != null &&
              stationParamJson.sts.ontimeafter != ''
            )
              condition.ontimeafter = Number(stationParamJson.sts.ontimeafter);
            if (
              stationParamJson.sts.ontimebefore != undefined &&
              stationParamJson.sts.ontimebefore != null &&
              stationParamJson.sts.ontimebefore != ''
            )
              condition.ontimebefore = Number(stationParamJson.sts.ontimebefore);
            if (
              stationParamJson.sts.ontime != undefined &&
              stationParamJson.sts.ontime != null &&
              stationParamJson.sts.ontime != ''
            ) {
              if (
                stationParamJson.sts.ontime === true ||
                Boolean(stationParamJson.sts.ontime) == true
              )
                condition.ontime = true;
            }
            if (
              stationParamJson.sts.ratevalue != undefined &&
              stationParamJson.sts.ratevalue != null &&
              stationParamJson.sts.ratevalue != ''
            )
              condition.ratevalue = Number(stationParamJson.sts.ratevalue);
            if (
              stationParamJson.sts.rateafter != undefined &&
              stationParamJson.sts.rateafter != null &&
              stationParamJson.sts.rateafter != ''
            )
              condition.rateafter = Number(stationParamJson.sts.rateafter);
            if (
              stationParamJson.sts.ratebefore != undefined &&
              stationParamJson.sts.ratebefore != null &&
              stationParamJson.sts.ratebefore != ''
            )
              condition.ratebefore = Number(stationParamJson.sts.ratebefore);
          }
        }
        statisticsCondition.value = condition;
        console.log('QmsExchangeDataIndex setStatisticsCondition', statisticsCondition.value);
      }
      /**
       * 打开设置统计条件弹出框
       */
      function onExchangeDataStatisticButtonClick() {
        let propsData: QcUnifyTransToChildProps = {
          moduleName: '数据统计条件',
          operateString: '设置',
          condition: statisticsCondition.value,
        };
        console.log(
          'QmsExchangeDataIndex onExchangeDataStatisticButtonClick',
          statisticsCondition.value,
        );
        openDataStsFormModal(true, propsData);
      }

      /**
       * 打开查看日志弹出框
       */
      function onExchangeDataLogView() {
        let categoryId = undefined; //交换数据分类ID
        let stationCode = ''; //交换站点ID
        let selectStcds = stcd.value;
        let firstSelectStcd = selectStcds[0x0];
        if (!Array.isArray(firstSelectStcd)) {
          firstSelectStcd = selectStcds;
        }
        if (Array.isArray(firstSelectStcd)) {
          if (firstSelectStcd.length === 0x3) {
            categoryId = firstSelectStcd[0x1];
            // 获取当前对象编码
            stationCode = firstSelectStcd[0x2];
          }
        }

        //获取交换数据分类信息，根据交换数据分类ID获取，方便获后面获取分类中的站点集合
        let category = undefined;
        if (
          categoriesData.value != undefined &&
          categoriesData.value != null &&
          categoriesData.value.length > 0x0
        ) {
          categoriesData.value.forEach((categoryObj) => {
            // 获取当前对象的参数赋给编辑参数对象
            if (categoryId === categoryObj.category.id) {
              //找到交换数据分类ID的对象
              category = categoryObj;
              //再根据站点编码分类中的站点信息
            }
          });
        }

        // 设置站点选择项
        let selectOptions = [];
        if (category != undefined && category != null) {
          if (
            category.stations != undefined &&
            category.stations != null &&
            category.stations.length > 0x0
          ) {
            category.stations.forEach((station) => {
              let option = {
                label: station.stnm,
                value: station.stcd,
              };
              selectOptions.push(option);
            });
          }
        }
        console.log(selectOptions, 'selectOptions');
        let propsData: QcUnifyTransToChildProps = {
          moduleName: '交换数据操作日志',
          operateString: selectOptions.filter((item) => item.value == stationCode)[0].label,
          cid: categoryId,
          stcd: stationCode,
          stcdOption: selectOptions,
        };
        openExchangeDataLogModal(true, propsData);
      }

      onBeforeMount(() => {
        console.log('QmsExchangeDataIndex onBeforeMount');
        //获取栏目ID，先从url传参中获取，如果没有再从store中获取；可以直接输入url地址打开网页，所以先从url中获取
        //测试--获取路由地址传参 url中的参数使用params获取
        console.log(
          'QmsExchangeDataIndex onBeforeMount router.params',
          router.currentRoute.value.params,
        );
        console.log(
          'QmsExchangeDataIndex onBeforeMount router.query',
          router.currentRoute.value.query,
        );
        console.log(
          'QmsExchangeDataIndex onBeforeMount router.fullPath',
          router.currentRoute.value.fullPath,
        );
        //从router.fullPath中获取传入的参数，并对空元素进行去除
        let param1 = '';
        let param2 = '';
        let fullPathArray = router.currentRoute.value.fullPath.split('/');
        if (fullPathArray != undefined && fullPathArray != null && fullPathArray.length > 0x0) {
          let notEmptyPathArray = fullPathArray.filter((str) => str.length > 0x0);
          if (notEmptyPathArray.length > 0x2) param1 = notEmptyPathArray[0x2];
          if (notEmptyPathArray.length > 0x3) param2 = notEmptyPathArray[0x3];
        }
        initQueryConditionData(param1, param2);
      });
      function lazyLoading() {
        let dom = document.querySelector('.ant-table-body');
        dom.addEventListener('scroll', (v) => {
          const scrollDistance = dom.scrollHeight - dom.scrollTop - dom.clientHeight;
          // if (scrollDistance <= 0) {  //分辨率问题，如果设置 100% ，滑倒最底部，scrollDistance的值 可能为 0.201 到 -0.201
          if (scrollDistance <= 120) {
            endIndex.value = endIndex.value + 100;
            tableData.value = totalData.value.slice(0, endIndex.value);
          }
        });
      }
      onMounted(() => {
        nextTick(() => {
          lazyLoading();
        });
      });
      onUnmounted(() => {
        console.log('QmsExchangeDataIndex.vue onUnmounted');
      });
      /**
       * 监听如果级联选择中的站点变换，根据当前选中的站点获取站点参数中的统计json配置
       */
      watch(
        () => stcd,
        (oldVal, newVal) => {
          console.log('watch stcd oldVal', oldVal.value);
          if (oldVal.value == undefined || oldVal.value == null) return;
          let selectStcds = stcd.value;
          //记录通道和分类所在的索引
          let channelIndex = -1;
          let categoryIndex = -1;
          let stationIndex = -1;
          let firstSelectStcd = selectStcds[0x0];
          //取值时需要根据是否支持多选，得到的结果不同
          //设置为不能多选时，初始选中第1个赋值为：[ [ 1, 1, "53010002" ] ]；人工操作选中1个赋值为：[ 1, 2, "53010002" ]
          //判断获取级联选择的值数组第1个，如果为数组则按数组方式获取，如果不为数组按对象方式获取--直接使用stcd作为数组进行获取
          if (!Array.isArray(firstSelectStcd)) {
            firstSelectStcd = selectStcds;
          }
          if (Array.isArray(firstSelectStcd)) {
            // 选中的站点数组长度为1，表示选中了整个通道
            if (firstSelectStcd.length >= 0x1) {
              let dataOptions = stcdOptions.value;
              console.log('watch stcd dataOptions', dataOptions);
              if (!dataOptions === false && dataOptions?.length > 0x0) {
                for (let i = 0; i < dataOptions?.length; i++) {
                  if (dataOptions[i].value == firstSelectStcd[0x0]) {
                    channelIndex = i;
                    break;
                  }
                }
                // 选中的站点数组长度为2，表示选中了整个数据分类
                if (firstSelectStcd.length >= 0x2 && channelIndex >= 0x0) {
                  let dataOptions = stcdOptions.value[channelIndex];
                  // console.log('watch stcd channelIndex=' + channelIndex + ' dataOptions', dataOptions);
                  if (
                    !dataOptions === false &&
                    !dataOptions.children === false &&
                    dataOptions.children.length > 0x0
                  ) {
                    for (let i = 0; i < dataOptions?.children.length; i++) {
                      if (dataOptions.children[i].value == firstSelectStcd[0x1]) {
                        categoryIndex = i;
                        break;
                      }
                    }
                    // 选中的站点数组长度为3，表示选中了指定的站点
                    if (firstSelectStcd.length >= 0x3 && categoryIndex >= 0x0) {
                      let dataOptions = stcdOptions.value[channelIndex].children[categoryIndex];
                      // console.log(
                      //   'watch stcd categoryIndex=' + categoryIndex + ' dataOptions',
                      //   dataOptions,
                      // );
                      if (
                        !dataOptions === false &&
                        !dataOptions.children === false &&
                        dataOptions.children.length > 0x0
                      ) {
                        for (let i = 0; i < dataOptions?.children.length; i++) {
                          if (dataOptions.children[i].value == firstSelectStcd[0x2]) {
                            stationIndex = i;
                            break;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
          // console.log(
          //   'watch stcd selectStcds=' +
          //     selectStcds +
          //     ' channelIndex=' +
          //     channelIndex +
          //     ' categoryIndex=' +
          //     categoryIndex +
          //     ' stationIndex=' +
          //     stationIndex,
          // );
          if (channelIndex >= 0x0 && categoryIndex >= 0x0 && stationIndex >= 0x0) {
            setStatisticsCondition(
              stcdOptions.value[channelIndex].children[categoryIndex].children[stationIndex],
            );
            stationname.value =
              stcdOptions.value[channelIndex].children[categoryIndex].children[stationIndex].label;
          } else setStatisticsCondition(undefined);
        },
        {
          deep: true,
        },
      );
      return {
        moment,
        tmrange,
        tmstsResult,
        stcd,
        endIndex,
        totalData,
        Cascader,
        searchFilter,
        stcdOptions,
        allSqls,
        statisticsResult,
        statisticsCondition,
        dataLoading,
        activeTabKey,
        getQueryConditionData,
        onExchangeDataQueryButtonClick,
        onExchangeDataAddButtonClick,
        onExchangeDataStatisticButtonClick,
        openDataStsFormModal,
        onExchangeTimeStsQueryButtonClick,
        onOpenTimeStsConditionModalClick,
        moduleTitle,
        stationname,
        tableColumns,
        editFormColumns,
        tableData,
        registerSaveModal,
        registerDataStsForm,
        registerTimeStsForm,
        registerExchangeDataLog,
        opSuccess,
        onStatisticsConfirmButtonClick,
        currentSqlEditFlag,
        chartComponentKey,
        chartMinTime,
        chartMaxTime,
        chartTimeType,
        chartYAxis,
        chartSeries,
        chartComponentKey2,
        chartMinTime2,
        chartMaxTime2,
        chartTimeType2,
        chartYAxis2,
        chartSeries2,
        onExchangeDataLogView,
      };
    },
  });
</script>
<style scoped lang="less"></style>
